package cloud.xlh.my_system.config;

import cloud.xlh.exceptionhandle.service.impl.BusinessExceptionEnum;
import cloud.xlh.my_system.utils.RsaUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.YamlMapFactoryBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.Consumer;

/**
 * Created with IntelliJ IDEA.
 *
 * @ project name : xlh_osms
 * @ Author: XuLeHuang
 * @ Date: 2023/1/27 19:13
 * @ Description: 密文RSA解密程序
 */
public class EnvironmentDecryptConfig implements EnvironmentPostProcessor {
    @Value("${key.properties.location}")
    private String keyPropertiesLocation;

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        environment.getPropertySources().stream().forEach(new Consumer<PropertySource<?>>() {
            @Override
            public void accept(PropertySource<?> propertySource) {
                if (propertySource.getName().contains("application.yml") || propertySource.getName().contains("application.properties")) {
                    MapPropertySource mapPropertySource = (MapPropertySource) propertySource;
                    Map map = new HashMap<String , String>();
                    Set<Map.Entry<String, Object>> entrySet = mapPropertySource.getSource().entrySet();
                    entrySet.forEach(new Consumer<Map.Entry<String, Object>>() {
                        @Override
                        public void accept(Map.Entry<String, Object> stringObjectEntry) {
                            String value = stringObjectEntry.getValue().toString();
                            if (value.startsWith("ENC(") && value.endsWith(")")) {
                                try {
                                    map.put(stringObjectEntry.getKey() , RsaUtil.decrypt(stringObjectEntry.getValue().toString().substring(4).replace(")" , "") , getSecret()));
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    throw BusinessExceptionEnum.DECRYPT_FAIL.newException();
                                }
                            } else {
                                map.put(stringObjectEntry.getKey() , stringObjectEntry.getValue().toString());
                            }
                        }
                    });
                    environment.getPropertySources().replace(propertySource.getName() , new MapPropertySource(propertySource.getName() , map));
                }
            }
        });
    }

    public String getSecret() {
        YamlMapFactoryBean yamlMapFactoryBean = new YamlMapFactoryBean();
        //可以加载多个yml文件
        yamlMapFactoryBean.setResources(new ClassPathResource("application.yml"));
        //通过getObject()方法获取Map对象
        Map<String, Object> map = yamlMapFactoryBean.getObject();
        System.out.println(map);
        String filePath = (String)map.get("keyPropertiesLocation");
        Properties properties = new Properties();
        try {
            FileInputStream fileInputStream = new FileInputStream(filePath);
            properties.load(fileInputStream);
        } catch (Exception e) {
            e.printStackTrace();
            throw BusinessExceptionEnum.FILE_LOAD_EXCEPTION.newException();
        }
        String rsaPrivateKey = properties.getProperty("rsaPrivateKey");
        return rsaPrivateKey;
    }
}
